package xyz.ibenben.zhongdian.system.service.impl;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xyz.ibenben.zhongdian.common.annotation.SystemServiceLog;
import xyz.ibenben.zhongdian.common.constants.Constants;
import xyz.ibenben.zhongdian.system.dao.InnerMailDao;
import xyz.ibenben.zhongdian.system.entity.InnerMail;
import xyz.ibenben.zhongdian.system.entity.InnerMailRecord;
import xyz.ibenben.zhongdian.system.entity.sys.SysUser;
import xyz.ibenben.zhongdian.system.mapper.InnerMailMapper;
import xyz.ibenben.zhongdian.system.service.InnerMailRecordService;
import xyz.ibenben.zhongdian.system.service.InnerMailService;
import xyz.ibenben.zhongdian.system.service.sys.SysUserService;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 站内信服务实现类
 * 提供了一些基本的服务，如获取公告、查询个人消息、查询每条消息的详细信息等方法
 * 主要用于用户之间通信使用此类来维护
 *
 * @author chenjian
 * @since 2017年9月27日上午10:57:28
 */
@Service("innerMailService")
public class InnerMailServiceImpl extends ServiceImpl<InnerMail> implements InnerMailService {
	private final InnerMailDao innerMailDao;
	private final InnerMailMapper innerMailMapper;
	private final InnerMailRecordService innerMailRecordService;
	private final SysUserService sysUserService;

	@Autowired
	public InnerMailServiceImpl(InnerMailDao innerMailDao, InnerMailMapper innerMailMapper, InnerMailRecordService innerMailRecordService, SysUserService sysUserService) {
		this.innerMailDao = innerMailDao;
		this.innerMailMapper = innerMailMapper;
		this.innerMailRecordService = innerMailRecordService;
		this.sysUserService = sysUserService;
	}

	/**
	 * save站内信记录
	 * @param entity 参数
	 * @param request 参数
	 * @return 返回值
	 */
	@Transactional
	@Override
	@SystemServiceLog(description = "save站内信记录")
	public int save(InnerMail entity, HttpServletRequest request) {
		entity.setCreateId((Long)request.getSession().getAttribute(Constants.SESSIONID));
		entity.setCreateTime(new Date());
		entity.setUpdateId((Long)request.getSession().getAttribute(Constants.SESSIONID));
		entity.setUpdateTime(new Date());
		int result = innerMailDao.insert(entity);
		if(entity.getType().ordinal() == 0 || entity.getType().ordinal() == 1){
			List<SysUser> userList = sysUserService.findByType(entity.getType().ordinal());
			for(SysUser user: userList){
				this.buildEntity(entity.getId(), user.getId(), request);
			}
		}else{
			this.buildEntity(entity.getId(), entity.getToId(), request);
		}
		return result;
	}

	/**
	 * 构建实体类
	 * @param id 参数
	 * @param toId 参数
	 * @param request 参数
	 */
	private void buildEntity(Long id, Long toId, HttpServletRequest request){
		InnerMailRecord imr = new InnerMailRecord();
		imr.setImId(id);
		imr.setToId(toId);
		imr.setIsRead(false);
		imr.setSendTime(new Date());
		innerMailRecordService.save(imr, request);
	}

	/**
	 * delete站内信记录
	 * @param key 参数
	 * @param request 参数
	 * @return 返回值
	 */
	@Transactional
	@Override
	@SystemServiceLog(description = "delete站内信记录")
	public int delete(Object key, HttpServletRequest request) {
		int result = 0;
		int resultIMR = innerMailRecordService.deleteByInnerMailKey(key, request);
		InnerMail entity = this.selectByKey(key);
		entity.setDelFlag(0);
		entity.setDelId((Long)request.getSession().getAttribute(Constants.SESSIONID));
		entity.setDelTime(new Date());
		int resultIM = innerMailDao.updateByPrimaryKey(entity);
		if(resultIMR != 0 && resultIM != 0){
			result = resultIM;
		}
		return result;
	}

	/**
	 * findAllNoticeByUserId站内信记录
	 * @param userId 参数
	 * @param type 参数
	 * @return 返回值
	 */
	@Override
	@SystemServiceLog(description = "findAllNoticeByUserId站内信记录")
	public List<InnerMail> findAllNoticeByUserId(Long userId, String type) {
		Map<String, Object> map = new HashMap<>();
		map.put("userId", userId);
		map.put("isRead", false);
		map.put("type", type);
		return innerMailMapper.findAllNoticeByUserId(map);
	}

	/**
	 * selectByKeyAndUserId站内信记录
	 * @param id 参数
	 * @param request 参数
	 * @return 返回值
	 */
	@Transactional
	@Override
	@SystemServiceLog(description = "selectByKeyAndUserId站内信记录")
	public InnerMail selectByKeyAndUserId(Long id, HttpServletRequest request) {
		Long userId = (Long)request.getSession().getAttribute(Constants.SESSIONID);
		InnerMail innerMail = this.selectByKey(id);
		innerMail.setFromUserName(sysUserService.selectByKey(innerMail.getFromId()).getUsername());
		SysUser user = sysUserService.selectByKey(userId);
		InnerMailRecord record = innerMailRecordService.selectByMailIdAndUserId(id, userId);
		innerMail.setIsRead(record.getIsRead());
		innerMail.setSendTime(record.getSendTime());
		innerMail.setToId(record.getToId());
		innerMail.setToUserName(user.getUsername());
		record.setIsRead(true);
		innerMailRecordService.updateAll(record, request);
		return innerMail;
	}

	/**
	 * selectByKeyWithList站内信记录
	 * @param id 参数
	 * @return 返回值
	 */
	@Override
	@SystemServiceLog(description = "selectByKeyWithList站内信记录")
	public InnerMail selectByKeyWithList(Long id) {
		Map<String, Object> map = new HashMap<>();
		map.put("key", id);
		return innerMailMapper.findByPrimaryKey(map);
	}

	/**
	 * getAllDetail站内信记录
	 * @param title 参数
	 * @param isRead 参数
	 * @param request 参数
	 * @return 返回值
	 */
	@Override
	@SystemServiceLog(description = "getAllDetail站内信记录")
	public List<InnerMail> getAllDetail(String title, Boolean isRead, HttpServletRequest request) {
		Long userId = (Long)request.getSession().getAttribute(Constants.SESSIONID);
		SysUser user = sysUserService.selectByKey(userId);
		Map<String, Object> map = new HashMap<>();
		map.put("title", StringUtils.isNotBlank(title) ? "%" + title + "%" : title);
		map.put("type", user.getType() ? "FrontNotice" : "BackNotice");
		map.put("isRead", isRead);
		map.put("userId", userId);
		return innerMailMapper.findAllNoticeByUserId(map);
	}

	/**
	 * findCountByUserId站内信记录
	 * @param userId 参数
	 * @return 返回值
	 */
	@Override
	@SystemServiceLog(description = "findCountByUserId站内信记录")
	public int findCountByUserId(Long userId) {
		return innerMailRecordService.selectCountByUserId(userId);
	}

}
